package nl.tudelft.jpacman.npc.ghost;
import nl.tudelft.jpacman.board.BoardFactory;
import nl.tudelft.jpacman.board.Direction;
import nl.tudelft.jpacman.level.Level;
import nl.tudelft.jpacman.level.LevelFactory;
import nl.tudelft.jpacman.level.Player;
import nl.tudelft.jpacman.level.PlayerFactory;
import nl.tudelft.jpacman.points.PointCalculator;
import nl.tudelft.jpacman.sprite.PacManSprites;
import org.assertj.core.util.Lists;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class InkyTest {

    private GhostMapParser ghostMapParser;
    private Player player;

    @BeforeEach
    void setUp() {
        PacManSprites pacManSprites = new PacManSprites();
        BoardFactory boardfactory = new BoardFactory(pacManSprites);
        GhostFactory ghostFactory = new GhostFactory(pacManSprites);
        PlayerFactory playerFactory = new PlayerFactory(pacManSprites);
        LevelFactory levelFatory = new LevelFactory(pacManSprites, ghostFactory, mock(PointCalculator.class));
        ghostMapParser = new GhostMapParser( levelFatory, boardfactory, ghostFactory);
        player = playerFactory.createPacMan();
    }

    @Test
    void InkyInFront() {
        List<String> layout = Lists.newArrayList(
            "########################################",
            "#           I         P           B    #",
            "########################################"
        );
        Level level = ghostMapParser.parseMap(layout);
        Inky inky = Navigation.findUnitInBoard(Inky.class, level.getBoard());
        level.registerPlayer(player);
        player.setDirection(Direction.WEST);
        assertThat(inky.nextAiMove()).contains(Direction.WEST);
    }

    @Test
    void InkyBehind() {
        List<String> layout = Lists.newArrayList(
            "########################################",
            "#       I    P                   B     #",
            "########################################"
        );
        Level level = ghostMapParser.parseMap(layout);
        Inky inky = Navigation.findUnitInBoard(Inky.class, level.getBoard());
        level.registerPlayer(player);
        player.setDirection(Direction.EAST);
        assertThat(inky.nextAiMove()).contains(Direction.EAST);
    }


    @Test
    void InkyHasNoSquare() {
        List<String> layout = Lists.newArrayList(
            "########################################",
            "#                      P               #",
            "# B                                    #",
            "########################################"
        );
        Level level = ghostMapParser.parseMap(layout);
        assertThat(Navigation.findUnitInBoard(Inky.class, level.getBoard())).isEqualTo(null);
    }

    @Test
    void PacmanHasNoSquare() {
        List<String> layout = Lists.newArrayList(
            "########################################",
            "#     B                           I    #",
            "########################################"
        );
        Level level = ghostMapParser.parseMap(layout);
        Inky inky = Navigation.findUnitInBoard(Inky.class, level.getBoard());
        assertThat(inky.nextAiMove()).isEqualTo(Optional.empty());
    }


    @Test
    void BlinkyHasNoSquare() {
        List<String> layout = Lists.newArrayList(
            "########################################",
            "#                  P              I    #",
            "########################################"
        );
        Level level = ghostMapParser.parseMap(layout);
        Inky inky = Navigation.findUnitInBoard(Inky.class, level.getBoard());
        assertThat(inky.nextAiMove()).isEqualTo(Optional.empty());
    }
}
